home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-02-06 | 56.9 KB | 2,562 lines |
- ;-------- Initialisation routines ------------------------------------------
- ; Graphics_Init()
- ; Graphics_Close()
- ; Open_Screen(d0,d1,d2,d3,a0) width, height, depth, viewmodes, cmap
- ; Close_Screen(a0) screen
- ; Init_Mask(d0,d1,d2,d3,d4,d5) x_min,y_min,x_max,y_max,sreen x,screen y
- ; Free_Mask(a0) maskplane struct
-
- ;-------- Drawing routines -------------------------------------------------
- ; Fill_Polygon(a0,a1,d0,d1) screen, vertex list, npoints, colour
- ; Draw_Polygon(a0,a1,d0,d1) screen, vertex list, npoints, colour
- ; Draw_Line(a0,d0,d1,d2,d3,d4) screen, x1, y1, x2, y2, colour
- ; Write_Pixel(a0,d0,d1,d2) screen, x1, x2, colour
- ; Screen_Clear(a0) screen
- ; Show(a0) screen
-
- ;-------- Fade Routines------------------------------------------------
- ; Fade_To_White(a0,a1) source screen,source colourmap
- ; Fade_To_Black(a0,a1) source screen,source colourmap
- ; Fade(a0,a1,a2) screen,source,destination
-
- ;-------- IFF Handling routines reading and writing of bitmaps -------------
- ; Save_IFF(a0,a1)=filename APTR, screen ADDR
- ; Load_IFF(a0,a1)=filename APTR, screen ADDR
-
- ;-------- File handling Routines -------------------------------------------
- ; Load_Data(a0,d0,a1) filename, buffer length, destination
- ; Save_Data(a0,d0,a1) filename, buffer length, source
-
- ;-------- Text handling routines -------------------------------------------
- ; Write_Text(a0,a1,d0,d1,d2,d3) screen, text, x, y, colour, length
- ; Num_To_String(d0) word
-
- ;-------- Copper handling routines -------------------------------------
- ; Add_Copper(a0,a1) screen,copper list
-
- ;-------- Input Handling Routines ------------------------------------------
- ; GetKey()
-
-
- ;-------- Initialisation routines ------------------------------------------
- ; Graphics_Init()
- ; Graphics_Close()
- ; Open_Screen(d0,d1,d2,d3,a0) width, height, depth, viewmodes, cmap
- ; Close_Screen(a0) screen
- ; Init_Mask(d0,d1,d2,d3,d4,d5) x_min,y_min,x_max,y_max,sreen x,screen y
- ; Free_Mask(a0) maskplane struct
-
- include system.gs
- include custom/graphics_base.i
-
- xdef _Graphics_Init
- xdef _Graphics_Close
- xdef _Open_Screen
- xdef _Close_Screen
- xdef _Init_Mask
- xdef _Free_Mask
-
- xdef _Fill_Polygon
- xdef _Draw_Polygon
- xdef _Draw_Line
- xdef _Write_Pixel
- xdef _Screen_Clear
- xdef _Show
-
- xdef _Fade_To_White
- xdef _Fade_To_Black
- xdef _Fade
-
- xdef _Save_IFF
- xdef _Load_IFF
-
- xdef _Load_Data
- xdef _Save_Data
-
- xdef _Write_Text
- xdef _Num_To_String
-
- xdef _Add_Copper
-
- xdef _GetKey
-
-
- _Graphics_Init
- ; sets a high taskpri, opens the graphics library
- ; and loads a null view
- ; returns 0 if failure
- ; 1 if success
-
- PUSH d2-d7/a2-a6
-
- move.l #0,d7
-
- OPENLIB _graphics_lib,0,_GfxBase
- tst.l d0
- beq.s G_Init_Failed
-
- move.l 4.w,a6
- sub.l a1,a1 Zero - Find current task
- jsr _LVOFindTask(a6)
-
- move.l d0,a1
- moveq #127,d0 task priority to very high...
- jsr _LVOSetTaskPri(a6)
-
- move.l _GfxBase,a0 get GfxBase
- move.l gb_ActiView(a0),a1 get the current view
- move.l a1,_oldview store the address
-
- move.l #0,a1
- CALLGRAF LoadView load a null view
-
- CALLGRAF WaitTOF
-
- moveq.l #SETCHIPREV_AA,d0 set chipset to AGA
- CALLGRAF SetChipRev call SetChipRev
-
- move.l #1,d7
- G_Init_Failed
- move.l d7,d0
-
- PULL d2-d7/a2-a6
-
- rts
-
- _Graphics_Close
- ; closes the graphics library and restores the view
-
- PUSH d2-d7/a2-a6
-
- tst.l _oldview
- beq.s Graphics_Close_1
- move.l _oldview,a1 get the previous address view
- CALLGRAF LoadView load it into the view
-
- CALLGRAF WaitTOF wait a bit
- Graphics_Close_1
- tst.l _GfxBase
- beq.s Graphics_Close_2
- CLOSELIB _GfxBase
- Graphics_Close_2
- PULL d2-d7/a2-a6
- rts
-
-
- _Open_Screen
- ; opens a view
- ; d0.l=pixel width
- ; d1.l=pixel height
- ; d2.l=depth
- ; d3.l=viewmodes
- ; a0.l=colourmap
-
- ; d0.l=returns screen address
-
- PUSH d2-d7/a2-a6
-
- movem.l d0-d3/a0,-(sp) store inputs
-
- moveq.l #0,d7 set d7 to failure
-
- move.l #Screen_Store_SIZEOF,d0 the screen storage structure
- move.l #MEMF_ANY!MEMF_CLEAR,d1 don't care about the memory
- CALLEXEC AllocMem allocate it
-
- tst.l d0
- beq Screen_Failed failed to allocate my screen
-
- move.l d0,a4 base of storage structure
-
- ; moveq.l #0,d7
-
- move.l #18,d0 size of a view structure
- move.l #MEMF_ANY!MEMF_CLEAR,d1 don't care about the memory
- CALLEXEC AllocMem allocate memory for view struct
- move.l d0,SS_View(a4) store the address
-
- tst.l d0
- beq Screen_Failed failed to open the view structure
-
- move.l SS_View(a4),a1 init view structure
- CALLGRAF InitView
-
- move.l #VIEW_EXTRA_TYPE,d0 set up a view extra
- CALLGRAF GfxNew structure for the view
-
- move.l d0,SS_ViewExtra(a4) store the viewextra structure
-
- tst.l d0
- beq Screen_Failed couldn't allocate one so off we go
-
- move.l SS_View(a4),a0 associate view extra
- move.l SS_ViewExtra(a4),a1 with view
- CALLGRAF GfxAssociate
-
- move.l SS_View(a4),a0 tell the view struct
- move.l #EXTEND_VSTRUCT,v_Modes(a0) that there is a view extra
-
- move.l #0,a1 open the monitor and
- move.l #DEFAULT_MONITOR_ID,d0 get it's default spec
- CALLGRAF OpenMonitor
- move.l d0,SS_MonSpec(a4)
-
- tst.l d0
- beq Screen_Failed couldn't allocate the monitor
-
- move.l SS_ViewExtra(a4),a0 put the monitor spec
- move.l SS_MonSpec(a4),ve_Monitor(a0) into the view extra
-
- move.l #40,d0 size of a bitmap struct
- move.l #MEMF_ANY!MEMF_CLEAR,d1 don't care about the memory
- CALLEXEC AllocMem allocate it
-
- move.l d0,SS_BitMap(a4)
-
- tst.l d0
- beq Screen_Failed couldn't allocate a bitmap structure
-
- move.l SS_BitMap(a4),a0 set up the bitmap
- move.l 8(sp),d0 NPLANES
- move.l (sp),d1 WIDTH
- move.l 4(sp),d2 HEIGHT
- CALLGRAF InitBitMap
-
- move.l (sp),d0 WIDTH
- lsr.l #3,d0 /8
- muls.l 4(sp),d0 *HEIGHT
- muls.l 8(sp),d0 *NPLANES
- move.l #MEMF_CHIP!MEMF_CLEAR,d1 chip mem
- CALLEXEC AllocMem allocate the memory
-
- move.l d0,SS_Screen(a4)
-
- tst.l d0
- beq Screen_Failed couldn't allocate a screen memory
-
- move.l SS_BitMap(a4),a2 get the bitmap struct
- lea bm_Planes(a2),a2 address of bitplanes
- move.l SS_Screen(a4),a3 screen 1 :-prev alloc
-
- move.l (sp),d0 WIDTH
- lsr.l #3,d0 /8
- muls.l 4(sp),d0 *HEIGHT
-
- move.l 8(sp),d7 NPLANES
- sub.l #1,d7 -1
- .bpl_loop
- move.l a3,(a2)+ put bitplane into struct
- add.l d0,a3 add plane size
- dbra d7,.bpl_loop loop round
-
- move.l #12,d0 size of rasinfo structure
- move.l #MEMF_ANY!MEMF_CLEAR,d1 don't care about the memory
- CALLEXEC AllocMem memory for rasinfo struct
-
- move.l d0,SS_RasInfo(a4)
-
- tst.l d0
- beq Screen_Failed couldn't allocate a rasinfo struct
-
- move.l SS_RasInfo(a4),a0
- move.l SS_BitMap(a4),a1
- move.l a1,ri_BitMap(a0) rasinfo into bitmap
-
- move.l #40,d0 size of a viewport structure
- move.l #MEMF_ANY!MEMF_CLEAR,d1 don't care about the memory
- CALLEXEC AllocMem memory for viewport struct
-
- move.l d0,SS_ViewPort(a4)
-
- tst.l d0
- beq Screen_Failed couldn't allocate the viewport struct
-
- move.l d0,a0 viewport address into a0
- CALLGRAF InitVPort initialise the viewport
-
- move.l SS_ViewPort(a4),a0
- move.w 14(sp),vp_Modes(a0) viewmodes into viewport
-
- move.l SS_View(a4),a1 viewport is already in a0
- move.l a0,v_ViewPort(a1) associate the view and viewport
-
- move.l SS_RasInfo(a4),a1 viewport already in a0
- move.l a1,vp_RasInfo(a0) associate the vport & rasinfo
- move.w 2(sp),vp_DWidth(a0) WIDTH
- move.w 6(sp),vp_DHeight(a0) HEIGHT
-
- move.l #VIEWPORT_EXTRA_TYPE,d0 gfx extra type
- CALLGRAF GfxNew make a vpextra struct
-
- move.l d0,SS_ViewPortExtra(a4) store the vpextra address
-
- tst.l d0
- beq Screen_Failed couldn't allocate a vpextra
-
- lea vctags,a0 the vctag structure
- ; lea 12(a0),a0
- move.l SS_ViewPortExtra(a4),12(a0) vpextra into vctags
-
- move.l #88,d0 size of a dim info structure
- move.l #MEMF_ANY!MEMF_CLEAR,d1 don't care about the memory
- CALLEXEC AllocMem allocate memory for diminfo struct
-
- move.l d0,SS_DimensionInfo(a4)
-
- tst.l d0
- beq Screen_Failed couldn't allocate the memory
-
- move.l #0,a0
- move.l SS_DimensionInfo(a4),a1
- move.l #88,d0
- move.l #DTAG_DIMS,d1
- move.l #DEFAULT_MONITOR_ID,d2
- CALLGRAF GetDisplayInfoData get the diminfo struct
-
- move.l SS_ViewPortExtra(a4),a0 link these bits together
- lea vpe_DisplayClip(a0),a0
- move.l SS_DimensionInfo(a4),a1
- lea dim_Nominal(a1),a1
- move.l (a1)+,(a0)+
- move.l (a1),(a0)
-
- move.l #DEFAULT_MONITOR_ID,d0 get the display ID
- CALLGRAF FindDisplayInfo for this display!
-
- lea vctags,a0
- lea 20(a0),a0 store this in the tag list
- move.l d0,(a0)
-
- moveq.l #0,d0 clear d0
- move.l 8(sp),d1 set bit number for no of colours
- bset d1,d0
- CALLGRAF GetColorMap allocate a colourmap structure
-
- move.l d0,SS_ColorMap(a4)
-
- tst.l d0
- beq Screen_Failed couldn't allocate a colourmap struct
-
- lea vctags,a0
- lea 4(a0),a0 stick the vieport into
- move.l SS_ViewPort(a4),a1 the tag list structure
- move.l a1,(a0)
-
- move.l SS_ColorMap(a4),a0
- lea vctags,a1
- CALLGRAF VideoControl
-
- tst.l d0
- bne Screen_Failed
-
- move.l #100,d0 size of a rastport structure
- move.l #MEMF_ANY!MEMF_CLEAR,d1 don't care about the memory
- CALLEXEC AllocMem memory for rastport structure
-
- move.l d0,SS_RastPort(a4)
-
- tst.l d0
- beq.s Screen_Failed couldn't allocate a rastport
-
- move.l d0,a1
- CALLGRAF InitRastPort init the rastport
-
- move.l SS_BitMap(a4),a0
- move.l SS_RastPort(a4),a1
- move.l a0,rp_BitMap(a1) bitmap struct into rastport
-
-
- move.l SS_ViewPort(a4),a0
- move.l 16(sp),a1 colortable into a0
- CALLGRAF LoadRGB32 load the colortable into the viewport
-
- move.l SS_View(a4),a0
- move.l SS_ViewPort(a4),a1
- CALLGRAF MakeVPort make the viewport
-
- tst.l d0
- bne.s Screen_Failed couldn't make the viewport
-
- move.l SS_View(a4),a1
- CALLGRAF MrgCop build the copperlist
-
- tst.l d0
- bne.s Screen_Failed couldn't build the copperlist
-
- move.l SS_View(a4),a1 all done so
- CALLGRAF LoadView load the view up :-)<-<
-
- movem.l (sp)+,d0-d3/a0 outputs back out.
-
- move.l d0,SS_Width(a4) store the width
- move.l d1,SS_Height(a4) store the height
- move.l d2,SS_Planes(a4) store the number of planes
- move.l a0,SS_ColorTable(a4) store the colourtable
-
- move.l a4,d7 screen store base address
- Screen_Failed
- move.l d7,d0 return value.
- bne.s Screen_Done not zero so out we go
- movem.l (sp)+,d0-d3/a0 pull outputs off if we haven't done it
- Screen_Done
-
- PULL d2-d7/a2-a6
-
- rts all done!
-
- _Close_Screen:
- ; Closes a view
- ; in:-a0=screen storage structure
-
- PUSH d2-d7/a2-a6
-
- move.l a0,a4
-
- move.l SS_UserCopperList(a4),a0
- tst.l a0 have we got any user coppers ?
- beq.s Close_Screen14
- move.l SS_ViewPort(a4),a0
- CALLGRAF FreeVPortCopLists free the user copperlists
-
- Close_Screen14
- move.l SS_View(a4),a0
- tst.l a0 have we got a view structure ?
- beq.s Close_Screen12
- lea v_LOFCprList(a0),a0
- move.l (a0),a0
- CALLGRAF FreeCprList free the copper lists
-
- move.l SS_RastPort(a4),a1
- tst.l a1 have we got a rastport struct ?
- beq.s Close_Screen12
- move.l #100,d0
- CALLEXEC FreeMem free the rastport
-
- Close_Screen13
- move.l SS_View(a4),a1
- tst.l a1 have we got a view structure ?
- beq.s Close_Screen12
- move.l #18,d0
- CALLEXEC FreeMem free the view structure
- Close_Screen12
- move.l SS_ViewPort(a4),a0
- tst.l a0 have we got a viewport struct ?
- beq.s Close_Screen11
- CALLGRAF FreeVPortCopLists free the viewport copper lists
- Close_Screen11
- move.l SS_ColorMap(a4),a0
- tst.l a0 colour map structure ?
- beq.s Close_Screen10
- CALLGRAF FreeColorMap free the colourmap structure
- Close_Screen10
- move.l SS_ViewPortExtra(a4),a0
- tst.l a0 vpextra structure ?
- beq.s Close_Screen9
- CALLGRAF GfxFree free it
- Close_Screen9
- move.l SS_MonSpec(a4),a0
- tst.l a0 have we got a monitor spec ?
- beq.s Close_Screen8
- CALLGRAF CloseMonitor close the monitor spec
- Close_Screen8
- move.l SS_BitMap(a4),a1
- tst.l a1 bitmap structure ?
- beq.s Close_Screen7
- move.l #40,d0
- CALLEXEC FreeMem free it.
- Close_Screen7
- move.l SS_Screen(a4),a1
- tst.l a1 have we got bitplane memory ?
- beq.s Close_Screen6
- move.l SS_Width(a4),d0 WIDTH
- lsr.l #3,d0 /8
- muls.l SS_Height(a4),d0 *HEIGHT
- muls.l SS_Planes(a4),d0 *NPLANES
- CALLEXEC FreeMem free the memory
- Close_Screen6
- move.l SS_RasInfo(a4),a1
- tst.l a1 have we got a ras info structure ?
- beq.s Close_Screen5
- move.l #12,d0
- CALLEXEC FreeMem free it
- Close_Screen5
- move.l SS_ViewPort(a4),a1
- tst.l a1 have we got a viewport structure ?
- beq.s Close_Screen4
- move.l #40,d0
- CALLEXEC FreeMem free it.
- Close_Screen4
- move.l SS_ViewExtra(a4),a0
- tst.l a0 have we got a view extra struct ?
- beq.s Close_Screen3
- CALLGRAF GfxFree free it.
- Close_Screen3
- move.l SS_DimensionInfo(a4),a1
- tst.l a1 a dim info struct ?
- beq.s Close_Screen2
- move.l #88,d0
- CALLEXEC FreeMem free the memory.
- Close_Screen2
- move.l a4,a1
- move.l #Screen_Store_SIZEOF,d0
- CALLEXEC FreeMem free the screen store memory.
- Close_Screen1
- moveq.l #0,d0
-
- PULL d2-d7/a2-a6
-
- rts
-
-
- _Init_Mask
- ; allocates a maskplane to be linked into
- ; a screen for the polygon filling
- ; operations
- ; d0.l=x_min
- ; d1.l=y_min
- ; d2.l=x_max
- ; d3.l=y_max
- ; d4=screen x
- ; d5-screen y
-
- ; returns
- ; d0=maskplane address
-
- ;*** Notes This could do with some better error checking!!!
-
- PUSH d2-d7/a2-a6
-
- PUSH d0-d3 store the inputs
-
- move.l #MaskPlane_SIZEOF,d0 enough space for a maskplane
- move.l #MEMF_ANY!MEMF_CLEAR,d1 any type of memory
- CALLEXEC AllocMem allocate it
-
- move.l d0,d7 store base address of the mem.
-
- move.l d0,a3 get memory address
-
- PULL d0-d3 inputs of stack
-
- move.w d0,MP_Clip_X_Min(a3) store min clip x
- move.w d1,MP_Clip_Y_Min(a3) store min clip y
- move.w d2,MP_Clip_X_Max(a3) store max clip x
- move.w d3,MP_Clip_Y_Max(a3) store max clip y
-
- lsr.l #3,d4 the bit size of the mask memory.
- muls d5,d4 times the height of the memory
-
- move.l d4,(a3)+ store the memory size in the struct
-
- move.l d4,d0
- move.l #MEMF_CHIP!MEMF_CLEAR,d1 chip memory
-
- CALLEXEC AllocMem allocate the mask memory
-
- move.l d0,(a3)+ store the memory area
-
- move.l d7,d0 return base address of mem.
-
- PULL d2-d7/a2-a6
-
- rts
-
- _Free_Mask:
- ; Frees a previously allocated maskplane
-
- ; a0.l=maskplane address returned by Init_Mask
-
- ;*** like above this could use some better error checking!!!
-
- PUSH d2-d7/a2-a6
-
- move.l a0,a5
- move.l MP_MaskPlane(a5),a1
- move.l MP_PlaneSize(a5),d0
- CALLEXEC FreeMem free the mask memory
-
- move.l a5,a1
- move.l #MaskPlane_SIZEOF,d0
- CALLEXEC FreeMem free the maskplane structure memory
-
- PULL d2-d7/a2-a6
-
- rts
-
- ;------------------------------------------------------------------------
-
- ;-------- Drawing routines -------------------------------------------------
- ; Fill_Polygon(a0,a1,d0,d1) screen, vertex list, npoints, colour
- ; Draw_Polygon(a0,a1,d0,d1) screen, vertex list, npoints, colour
- ; Draw_Line(a0,d0,d1,d2,d3,d4) screen, x1, y1, x2, y2, colour
- ; Write_Pixel(a0,d0,d1,d2) screen, x1, x2, colour
-
- _Fill_Polygon
- ; a0=screen to draw onto
- ; a1=list of vertices
- ; d0=npoints
- ; d1=colour
-
- PUSH d2-d7/a2-a6
-
- PUSH a0/d1 store the screen and number of points
- exg.l a0,a1 swap the screen and point list.
- clip:
- ; clips a polygon
- ; internal routine called by Fill_Polygon
- ; DONT CALL THIS PROCUDURE YOURSELF
-
- ; d0=number of points coming in
- ; a0=points coming in
- ; a1=screen structure
-
- move.l SS_MaskPlane(a1),a6 get the maskplane address
- lea clip_out,a2 temporary variable
-
- ; the source buffer is already in a0
-
- lea MP_PointBuffer(a6),a1 initial destination buffer
- move.l a1,a4 store this address
-
- clr.w (a2) clear the clip out variable
-
- move.w d0,d7 get the number of points
- beq clip_end no points so jump out
- subq.w #1,d7 sub 1 for the loop
-
- move.w (a0)+,d5 get the first x point
- move.w (a0)+,d6 get the first y point
- move.w MP_Clip_X_Min(a6),d0 get the clip value
- cmp.w d0,d5 compare the point to the clip value
-
- bge.s xmin_save point is in so store it
- bra.s xmin_update point is out so update the temp var.
-
- xmin_next:
- move.w (a0)+,d3 get the next x point
- move.w (a0)+,d4 get the next y point
- move d3,d5 store these values
- move d4,d6
-
- sub.w d0,d3 subtract the clip value
- bge.s xmin_x2in the point is in so check the other
-
- ; the point must be outside so check the other point
-
- sub.w d0,d1 subtract the clip value
- blt.s xmin_update do this if both points are outside
-
- ; if we get to here then the first point is outside but the
- ; second is inside so we have to clip the line
-
- beq.s .yint_out
-
- movem d5/d6,-(sp) store d5 and d6
- .yint_in move.w d2,d6 store the first y coord
- add.w d4,d6 add the second y coordinate onto this
- asr.w #1,d6 divide this by 2
- move.w d1,d5 get the x difference into d5
- add.w d3,d5 add the first x onto this
- asr.w #1,d5 divide this by 2
- beq.s .yint_end if this is 0 we have the intersect
- bgt.s .yint_loop greater than 0 so off we go
- ; less than zero
- move.w d5,d3 the x value goes into d3
- move.w d6,d4 the y value goes into d4
- bra.s .yint_in iterate backwards
- .yint_loop:
- move.w d5,d1 the x value goes into d1
- move.w d6,d2 y into d2
- bra.s .yint_in iterate backwards
- .yint_end:
- move.w d0,(a1)+ store the x value
- move.w d6,(a1)+ store the intersect value
- addq.w #1,(a2) increment the counter.
- movem (sp)+,d5/d6 pull the contents off the stack.
- .yint_out:
-
- bra.s xmin_update update the temp variables.
-
- xmin_x2in:
- ; the first point is in so check the second
-
- sub.w d0,d1 subtract the clip value
- bge.s xmin_save the point is in so save
-
- tst.w d3 check if d3 is 0
- beq.s .yint_out it is so jump off.
-
- movem d5/d6,-(sp) store d5 and d6
- .yint_in move.w d4,d6 store the first y coord
- add.w d2,d6 add the second y coordinate onto this
- asr.w #1,d6 divide this by 2
- move d3,d5 get the x difference into d5
- add.w d1,d5 add the first x onto this
- asr.w #1,d5 divide this by 2
- beq.s .yint_end if this is 0 we have the intersect
- bgt.s .yint_loop greater than 0 so off we go
- ; less than zero
- move d5,d1 the x value goes into d3
- move d6,d2 the y value goes into d4
- bra.s .yint_in iterate backwards
- .yint_loop:
- move d5,d3 the x value goes into d1
- move d6,d4 y into d2
- bra.s .yint_in iterate backwards
- .yint_end:
- move.w d0,(a1)+ store the x value
- move.w d6,(a1)+ store the intersect value
- addq.w #1,(a2) increment the counter.
- movem (sp)+,d5/d6 pull the contents off the stack.
- .yint_out:
-
- xmin_save:
- move.w d5,(a1)+ store the x coordinate
- move.w d6,(a1)+ store the y coordinate
- addq.w #1,(a2) increment the counter
- xmin_update:
- move d5,d1 move x into the other x
- move d6,d2 move the y into the other one
- dbf d7,xmin_next loop back.
-
- tst.w (a2) check if there are no points.
- beq.s clip_xmax no points so jump off.
-
- subq.w #4,a1 check if the first and last
- cmpm.l (a4)+,(a1)+ points are the same
- beq.s clip_xmax if they aren't copy the
- move.l -(a4),(a1) first to the last point and
- addq.w #1,(a2) increment the counter.
-
- clip_xmax:
- lea MP_PointBuffer(a6),a0 source buffer
- lea MP_PointBuffer2(a6),a1 destination buffer
- move.l a1,a4
-
- move.w (a2),d7
- beq clip_ymin no points so don't waste time
- subq.w #1,d7 decrement the counter
-
- clr.w (a2) clear the temporary variable
-
- move.w (a0)+,d5 get the first x point
- move.w (a0)+,d6 get the first y point
- move.w MP_Clip_X_Max(a6),d0 get the clip value
- cmp.w d5,d0 compare the point to the clip value
-
- bge.s xmax_save point is in so store it
- bra.s xmax_update point is out so update the temp var.
-
- xmax_next:
- move.w (a0)+,d3 get the next x point
- move.w (a0)+,d4 get the next y point
- move d3,d5 store these values
- move d4,d6
-
- sub.w d0,d3 subtract the clip value
- neg.w d3 negate the distance
- bge.s xmax_x2in the point is in so check the other
-
- ; the point must be outside so check the other point
-
- sub.w d0,d1 subtract the clip value
- neg.w d1 negate the distance
- blt.s xmax_update do this if both points are outside
-
- ; if we get to here then the first point is outside but the
- ; second is inside so we have to clip the line
-
- beq.s .yint_out
-
- movem d5/d6,-(sp) store d5 and d6
- .yint_in move.w d2,d6 store the first y coord
- add.w d4,d6 add the second y coordinate onto this
- asr.w #1,d6 divide this by 2
- move d1,d5 get the x difference into d5
- add.w d3,d5 add the first x onto this
- asr.w #1,d5 divide this by 2
- beq.s .yint_end if this is 0 we have the intersect
- bgt.s .yint_loop greater than 0 so off we go
- ; less than zero
- move d5,d3 the x value goes into d3
- move d6,d4 the y value goes into d4
- bra.s .yint_in iterate backwards
- .yint_loop:
- move d5,d1 the x value goes into d1
- move d6,d2 y into d2
- bra.s .yint_in iterate backwards
- .yint_end:
- move.w d0,(a1)+ store the x value
- move.w d6,(a1)+ store the intersect value
- addq.w #1,(a2) increment the counter.
- movem (sp)+,d5/d6 pull the contents off the stack.
- .yint_out:
-
- bra.s xmax_update update the temp variables.
-
- xmax_x2in:
- ; the first point is in so check the second
-
- sub.w d0,d1 subtract the clip value
- neg.w d1 negate the distance
- bge.s xmax_save the point is in so save
-
- tst.w d3 check if d3 is 0
- beq.s .yint_out it is so jump off.
-
- movem d5/d6,-(sp) store d5 and d6
- .yint_in move.w d4,d6 store the first y coord
- add.w d2,d6 add the second y coordinate onto this
- asr.w #1,d6 divide this by 2
- move d3,d5 get the x difference into d5
- add.w d1,d5 add the first x onto this
- asr.w #1,d5 divide this by 2
- beq.s .yint_end if this is 0 we have the intersect
- bgt.s .yint_loop greater than 0 so off we go
- ; less than zero
- move d5,d1 the x value goes into d3
- move d6,d2 the y value goes into d4
- bra.s .yint_in iterate backwards
- .yint_loop:
- move d5,d3 the x value goes into d1
- move d6,d4 y into d2
- bra.s .yint_in iterate backwards
- .yint_end:
- move.w d0,(a1)+ store the x value
- move.w d6,(a1)+ store the intersect value
- addq.w #1,(a2) increment the counter.
- movem (sp)+,d5/d6 pull the contents off the stack.
- .yint_out:
-
- xmax_save:
- move.w d5,(a1)+ store the x coordinate
- move.w d6,(a1)+ store the y coordinate
- addq.w #1,(a2) increment the counter
- xmax_update:
- move d5,d1 move x into the other x
- move d6,d2 move the y into the other one
- dbf d7,xmax_next loop back.
-
- tst.w (a2) check if there are no points.
- beq.s clip_ymin no points so jump off.
-
- subq #4,a1 check if the first and las
- cmpm.l (a4)+,(a1)+ points are the same
- beq.s clip_ymin if they aren't copy the
- move.l -(a4),(a1) first to the last point and
- addq.w #1,(a2) increment the counter.
-
- clip_ymin:
- lea MP_PointBuffer2(a6),a0 source buffer
- lea MP_PointBuffer(a6),a1 destination buffer
- move.l a1,a4
-
- move.w (a2),d7 counter into d7
- beq clip_ymax no points to do ? so jump off
- subq.w #1,d7 decrement the counter
-
- clr.w (a2) clear the clip out variable
-
- move.w (a0)+,d5 get the first x point
- move.w (a0)+,d6 get the first y point
- move.w MP_Clip_Y_Min(a6),d0 get the clip value
- cmp.w d0,d6 compare the point to the clip value
-
- bge.s ymin_save point is in so store it
- bra.s ymin_update point is out so update the temp var.
-
- ymin_next:
- move.w (a0)+,d3 get the next x point
- move.w (a0)+,d4 get the next y point
- move d3,d5 store these values
- move d4,d6
-
- sub.w d0,d4 subtract the clip value
- bge.s ymin_y2in the point is in so check the other
-
- ; the point must be outside so check the other point
-
- sub.w d0,d2 subtract the clip value
- blt.s ymin_update do this if both points are outside
- ; if we get to here then the first point is outside but the
- ; second is inside so we have to clip the line
-
- beq.s .xint_out
-
- movem d5/d6,-(sp) store d5 and d6
- .xint_in move.w d1,d5 store the first x coordinate
- add.w d3,d5 add on the second x coordinate
- asr.w #1,d5 divide this by 2
- move.w d2,d6 get the y difference into d6
- add.w d4,d6 add the second y coordinate
- asr.w #1,d6 divide this by 2
- beq.s .xint_end if this is 0 we have the intersect
- bgt.s .xint_loop greater than 0 so off we go
- ; less than zero
- move.w d6,d4 the y value goes into d4
- move.w d5,d3 the x value goes into d3
- bra.s .xint_in iterate backwards
- .xint_loop:
- move.w d5,d1 the y value into d1
- move.w d6,d2 x into d2
- bra.s .xint_in iterate backwards
-
- .xint_end:
- move.w d5,(a1)+ store the intersect value
- move.w d0,(a1)+ store the clip value
- addq.w #1,(a2) increment the counter
- movem (sp)+,d5/d6 pull the contents off the stack.
- .xint_out
-
- bra.s ymin_update update the temp variables.
-
- ymin_y2in:
- ; the first point is in so check the second
-
- sub.w d0,d2 subtract the clip value
- bge.s ymin_save the point is in so save
-
- tst.w d4 check if d3 is 0
- beq.s .xint_out it is so jump off.
-
- movem d5/d6,-(sp) store d5 and d6
- .xint_in move d3,d5 store the second x coord
- add.w d1,d5 add the first x coordinate onto this
- asr.w #1,d5 divide this by 2
- move d4,d6 get the y difference
- add.w d2,d6 add on the first y coordinate
- asr.w #1,d6 divide this by 2
- beq.s .xint_end if this is 0 we have the intersect
- bgt.s .xint_loop greater than 0 so off we go
- ; less than zero
- move d6,d2 the y value into d2
- move d5,d1 x into d1
- bra.s .xint_in iterate backwards
- .xint_loop:
- move d5,d3 x into d3
- move d6,d4 y into d4
- bra.s .xint_in iterate backwards.
-
- .xint_end:
- move.w d5,(a1)+ store the x value
- move.w d0,(a1)+ store the intersect value
- addq.w #1,(a2) increment the counter.
- movem (sp)+,d5/d6 pull the contents off the stack.
- .xint_out
-
- ymin_save:
- move.w d5,(a1)+ store the x coordinate
- move.w d6,(a1)+ store the y coordinate
- addq.w #1,(a2) increment the counter
-
- ymin_update:
- move d5,d1 move x into the other x
- move d6,d2 move the y into the other one
- dbf d7,ymin_next loop back.
-
- tst.w (a2) check if there are no points.
- beq.s clip_ymax no points so jump off.
-
- subq #4,a1 check if the first and last
- cmpm.l (a4)+,(a1)+ points are the same
- beq.s clip_ymax if they aren't copy the
- move.l -(a4),(a1) first to the last point and
- addq.w #1,(a2) increment the counter.
-
- clip_ymax:
- lea MP_PointBuffer(a6),a0 source buffer
- lea MP_PointBuffer2(a6),a1 destination buffer
- move.l a1,a4
-
- move.w (a2),d7 no points so don't waste time
- beq clip_end
- subq.w #1,d7 decrement the counter
-
- clr.w (a2) clear the temporary variable
-
- move.w (a0)+,d5 get the first x point
- move.w (a0)+,d6 get the first y point
- move.w MP_Clip_Y_Max(a6),d0 get the clip value
- cmp.w d6,d0 compare the point to the clip value
-
- bge.s ymax_save point is in so store it
- bra.s ymax_update point is out so update the temp var.
-
- ymax_next:
- move.w (a0)+,d3 get the next x point
- move.w (a0)+,d4 get the next y point
- move d3,d5 store these values
- move d4,d6
-
- sub.w d0,d4 subtract the clip value
- neg.w d4 negate the distance
- bge.s ymax_y2in the point is in so check the other
-
- ; the point must be outside so check the other point
-
- sub.w d0,d2 subtract the clip value
- neg.w d2 negate the distance
- blt.s ymax_update do this if both points are outside
-
- ; if we get to here then the first point is outside but the
- ; second is inside so we have to clip the line
-
- beq.s .xint_out
-
- movem d5/d6,-(sp) store d5 and d6
- .xint_in move d1,d5 store the first x coordinate
- add.w d3,d5 add the second x onto this
- asr.w #1,d5 divide this by 2
- move d2,d6 get the y distance
- add.w d4,d6 add on the second y coord
- asr.w #1,d6 divide this by 2
- beq.s .xint_end if this is 0 we have the intersect
- bgt.s .xint_loop greater than 0 so off we go
- ; less than zero
- move d6,d4 the y value goes into d4
- move d5,d3 the x value goes into d3
- bra.s .xint_in iterate backwards
- .xint_loop:
- move d5,d1 the x value goes into d1
- move d6,d2 y into d2
- bra.s .xint_in iterate backwards
- .xint_end:
- move.w d5,(a1)+ store the x value
- move.w d0,(a1)+ store the intersect value
- addq.w #1,(a2) increment the counter.
- movem (sp)+,d5/d6 pull the contents off the stack.
- .xint_out
-
- bra.s ymax_update update the temp variables.
-
- ymax_y2in:
- ; the first point is in so check the second
-
- sub.w d0,d2 subtract the clip value
- neg.w d2 negate the distance
- bge.s ymax_save the point is in so save
-
- ;x_intercept:
- tst.w d4 check if d3 is 0
- beq.s .xint_out it is so jump off.
-
- movem d5/d6,-(sp) store d5 and d6
- .xint_in move d3,d5 store the second x coord
- add.w d1,d5 add the first x coordinate onto this
- asr.w #1,d5 divide this by 2
- move d4,d6 get the y difference
- add.w d2,d6 add on the first y coordinate
- asr.w #1,d6 divide this by 2
- beq.s .xint_end if this is 0 we have the intersect
- bgt.s .xint_loop greater than 0 so off we go
- ; less than zero
- move d6,d2 the y value into d2
- move d5,d1 x into d1
- bra.s .xint_in iterate backwards
- .xint_loop:
- move d5,d3 x into d3
- move d6,d4 y into d4
- bra.s .xint_in iterate backwards.
- .xint_end:
- move.w d5,(a1)+ store the x value
- move.w d0,(a1)+ store the intersect value
- addq.w #1,(a2) increment the counter.
- movem (sp)+,d5/d6 pull the contents off the stack.
- .xint_out
-
- ymax_save:
- move.w d5,(a1)+ store the x coordinate
- move.w d6,(a1)+ store the y coordinate
- addq.w #1,(a2) increment the counter
-
- ymax_update:
- move d5,d1 move x into the other x
- move d6,d2 move the y into the other one
- dbf d7,ymax_next loop back.
-
- tst.w (a2) check if there are no points.
- beq.s clip_end no points so jump off.
-
- subq #4,a1 check if the first and last
- cmpm.l (a4)+,(a1)+ points are the same
- beq.s clip_end if they aren't copy the
- move.l -(a4),(a1) first to the last point and
- addq.w #1,(a2) increment the counter.
-
- clip_end:
- lea MP_PointBuffer2(a6),a1 the final resting place of the polygon
- move.w (a2),d0 get the number of points
- cmp.w #1,d0 only one point ?
- bne.s clip_poly no so jump off
- move.w #0,d0 if yes we don't bother drawing it.
- clip_poly
- PULL a0/d1
-
- tst.w d0 check if we have any points
- beq Fill_Poly_Done no then don't bother drawing
-
- move.w SS_Height+2(a0),y_min this section is used to calculate
- move.w #0,y_max the boundaries of the polygon
- move.w SS_Width+2(a0),x_min
- move.w #0,x_max
-
- move.b d1,-(sp) store the colour value.
-
- move.w d0,d7 number of points.
- subq.w #2,d7 subtract 2
-
- move.l a1,a2 store the base address of the points
-
- move.w (a1)+,d2 first x point
- move.w (a1)+,d3 first y point
- Fill_Poly_Loop
- move.w d2,d0 move the points into the other pos
- move.w d3,d1
- move.w (a1)+,d2 get the next x point
- move.w (a1)+,d3 get the next y point
-
- cmp.w x_min,d0 this section is used to calculate
- bgt.s x_great_x_min the boundaries of the polygon
- move.w d0,x_min it works by checking the maximum
- x_great_x_min:
- cmp.w x_max,d0 and minimum x and y values and
- blt.s x_check_done updating the variables accordingly.
- move.w d0,x_max
- x_check_done
- cmp.w y_min,d1
- bgt.s y_great_y_min
- move.w d1,y_min
- y_great_y_min
- cmp.w y_max,d1
- blt.s y_check_done
- move.w d1,y_max
- y_check_done
-
- movem.l d2-d7/a0-a1,-(sp) store lots of variables on the stack.
-
- Fill_Line
- ; Draws a line for filling a polygon
- ; internal routine DONT CALL!!!!
- ; d0,d1=x1,y1
- ; d2,d3=x2,y2
-
- ; a0=screen structure
-
- ; *** This line drawing routine bashes the hardware quite violently.
- ; *** It is not my work but is taken from the How To Code 7 manual.
- ; *** Thank you to those responsible for it!
-
- CALLGRAF OwnBlitter
-
- lea $dff000,a6
- move.l SS_Width(a0),d6
- lsr.w #3,d6
- move.l SS_MaskPlane(a0),a0
- move.l MP_MaskPlane(a0),a0
- cmp.w d1,d3
- beq noline
- ble.s lin1
- exg d1,d3
- exg d0,d2
- lin1: sub.w d2,d0
- move.w d2,d5
- asr.w #3,d2
- ext.l d2
- sub.w d3,d1
- muls d6,d3
- add.l d2,d3
- add.l d3,a0
- and.w #$f,d5
- move.w d5,d2
- eor.b #$f,d5
- ror.w #4,d2
- or.w #$0b4a,d2
- swap d2
- tst.w d0
- bmi.s lin2
- cmp.w d0,d1
- ble.s lin3
- move.w #$41,d2
- exg d1,d0
- bra.s lin6
- lin3: move.w #$51,d2
- bra.s lin6
- lin2: neg.w d0
- cmp.w d0,d1
- ble.s lin4
- move.w #$49,d2
- exg d1,d0
- bra.s lin6
- lin4: move.w #$55,d2
- lin6: asl.w #1,d1
- move.w d1,d4
- move.w d1,d3
- sub.w d0,d3
- ble.s lin5
- and.w #$ffbf,d2
- lin5: move.w d3,d1
- sub.w d0,d3
- or.w #2,d2
- lsl.w #6,d0
- add.w #$42,d0
- bltwt: btst #6,2(a6)
- bne.s bltwt
- bchg d5,(a0)
- move.l d2,bltcon0(a6)
- move.l #-1,bltafwm(a6)
- move.l a0,bltcpt(a6)
- move.w d1,bltapt+2(a6)
- move.l a0,bltdpt(a6)
- move.w d6,bltcmod(a6) ;width
- move.w d4,bltbmod(a6)
- move.w d3,bltamod(a6)
- move.w d6,bltdmod(a6) ;width
- move.l #-$8000,bltbdat(a6)
- move.w d0,bltsize(a6)
- noline:
- CALLGRAF DisownBlitter
-
- movem.l (sp)+,d2-d7/a0-a1 values off the stack
-
- dbra d7,Fill_Poly_Loop branch back till all lines are done
-
- move.l a0,a4
-
- move.w x_max,d0 calculate the offset into the bitmap
- lsr.w #4,d0 of the polygon in terms of the
- move.w d0,d2 calue that the blitter wants
- add.w d2,d2
- move.w y_max,d1
- mulu #40,d1
- add.w d2,d1
- move.w d1,bltstrt
-
- move.l SS_Width(a0),d6
- lsr.l #3,d6 byte width of the screen
- move.l SS_MaskPlane(a0),a0
- move.l MP_MaskPlane(a0),a0
-
- add.w d1,a0 this is the address of the first word
- ;of the polygon
-
- move.w x_min,d1 calculate the width of the polygon
- lsr.w #4,d1 in terms of a value that the
- sub.w d1,d0 blitter likes
- addq.w #1,d0
- move.w d0,bltwidth
-
- move.w d6,d2 calculate the blit modulo
- add.w d0,d0
- sub.w d0,d2
- move.w d2,blitmod
-
- move.w y_max,d0 calculate the size of the polygon
- sub.w y_min,d0 for the blitter
- addq.w #1,d0
- lsl.w #6,d0
- add.w bltwidth,d0
- move.w d0,blitsize
-
- CALLGRAF OwnBlitter This section fills in the polygon
- ;using the blitter fill mode
- CALLGRAF WaitBlit
-
- move.l #$dff000,a5
-
- move.l a0,bltapt(a5)
- move.l a0,bltdpt(a5)
-
- move.w d2,bltamod(a5)
- move.w d2,bltdmod(a5)
- move.w #%0000100111110000,bltcon0(a5)
- move.w #%0000000000001010,bltcon1(a5)
- move.l #$ffffffff,bltafwm(a5)
- move.w blitsize,bltsize(a5)
-
- pln_copy:
- ; This section copies the polygon from the maskplane
- ; to the desination plane memory using the blitter.
-
- move.l SS_Screen(a4),a0
- adda.w bltstrt,a0
- move.l SS_Planes(a4),d7
- subq.l #1,d7
-
- move.w blitmod,d0
-
- ; Get the colour off the stack into d6
-
- move.b (sp)+,d6
- extb.l d6
-
- ; Set the initial values for the blitter
-
- CALLGRAF WaitBlit
- move.w #$0002,bltcon1(a5)
- move.w d0,bltamod(a5)
- move.w d0,bltbmod(a5)
- move.w d0,bltdmod(a5)
- move.l SS_MaskPlane(a4),a1
- move.l MP_MaskPlane(a1),a1
-
- add.w bltstrt,a1
- move.w blitsize,d2
-
- nxtplane:
-
- ; The loop for the plane copy
-
- CALLGRAF WaitBlit
- move.l a1,bltapt(a5)
- move.l a0,bltbpt(a5)
- move.l a0,bltdpt(a5)
-
- ; shift the colour bit right
- ; if the carry bit is clear we want to clear the destination memory
- ; else we want to fill it
-
-
- lsr.w #1,d6
- bcc.s bltclr
-
- move.w #%0000110111111100,bltcon0(a5) 11011111100
-
- bra.s bltcopy
-
- bltclr:
- move.w #%0000110100001100,bltcon0(a5)
-
- bltcopy:
- ; do the copy to destination memory
-
- move.w d2,bltsize(a5)
-
- ; increment the plane pointer
-
- move.l SS_Width(a4),d0
- lsr.l #3,d0
- muls.l SS_Height(a4),d0
- add.l d0,a0
-
- ; loop back to the number of planes
-
- dbf d7,nxtplane
-
- CALLGRAF DisownBlitter
-
- ; clear the section of the maskplane occupied by the polygon
- ; using the blitter
-
- CALLGRAF OwnBlitter
- CALLGRAF WaitBlit
- move.l a1,bltdpt(a5)
- move.w blitmod,bltdmod(a5)
- move.w #$0002,bltcon1(a5)
- move.w #$100,bltcon0(a5)
- move.w blitsize,bltsize(a5)
- CALLGRAF DisownBlitter
- Fill_Poly_Done
- PULL d2-d7/a2-a6
-
- rts
-
-
-
-
-
- _Draw_Polygon
- ; a0=screen to draw onto
- ; a1=list of vertices
- ; d0=npoints
- ; d1=colour
-
- PUSH d2-d7/a2-a6
-
- move.b d1,-(sp) colour onto the stack
-
- move.w d0,d7 number of points onto counter
- subq.w #2,d7 decrement d7
-
- move.l a1,a2 store vertex list
-
- move.w (a1)+,d2 get first point
- move.w (a1)+,d3
- Poly_Loop
- move.w d2,d0 prev point onto first coords
- move.w d3,d1
- move.w (a1)+,d2 get next point
- move.w (a1)+,d3
-
- move.b (sp)+,d4 colour off stack
-
- movem.l d2-d7/a0-a1,-(sp)
-
- bsr.s _Draw_Line draw the line.
-
- movem.l (sp)+,d2-d7/a0-a1
-
- move.b d4,-(sp) colour onto stack
-
- dbra d7,Poly_Loop loop back to all lines
-
- move.b (sp)+,d4 restore stack
- Poly_Done
-
- PULL d2-d7/a2-a6
-
- rts
-
- _Draw_Line
- ; Draws a line
- ; d0,d1=x1,y1
- ; d2,d3=x2,y2
- ; d4=colour
-
- ; a0=screen structure
-
- ; *** Unlike the fill_polygon procedure this routine uses the bresenham
- ; *** line drawing algorithm.
- PUSH d2-d7/a2-a6
-
- move.b d4,-(sp)
-
- moveq.w #1,d6 d6=IC
-
- cmp.w d1,d3 (y2-y1)=dy
- bgt.s ascend branch if slope>0
-
- ; the line must be descending so swap the vertices
-
- exg d0,d2 exchange x1 and x2
- exg d1,d3 exchange y1 and y2
-
- ascend sub.w d1,d3 dy is now +ve
-
- sub.w d0,d2 (x2-x1)=dx
- bgt.s pos_slope branch if the slope is +ve
-
- ; the slope must be -ve so make ic -ve
-
- neg.w d6
- neg.w d2 now dx is +ve
-
- pos_slope
- cmp.w d2,d3 test dy-dx
- bgt.s HiSlope slope is >1
-
- ; the slope is <1 so increment x each time and check y
- ; d0=xs, d1=ys, d2=dx, d3=dy
-
- move.w d3,d5 dy into d5
- add.w d5,d5 error1
-
- move.w d5,d7 2*dy into d7
-
- move.w d2,d4 dx into d4
- add.w d4,d4 2*dx
-
- sub.w d4,d7 2*dy-2*dx
-
- move.w d7,d4 error2
-
- move.w d2,d7 dx as the counter
- subq.w #1,d7 dx-1
-
- add.w d3,d3 2*dy
- sub.w d2,d3 (2*dy)-dx:-initial value of D
-
- move.b (sp)+,d2
-
- line_loop1
- tst.w d3 test error
- bpl.s inc_y_and_x
- add.w d6,d0 add ic onto xs
- add.w d5,d3 increment error
- bra.s point_1
- inc_y_and_x
- add.w d6,d0 add ic onto xs
- addq.w #1,d1 increment ys
- add.w d4,d3 increment error
- point_1
- PUSHALL
- cmp.w #0,d0 check x minimum
- bmi.s no_line_point_1
-
- cmp.w SS_Width+2(a0),d0
- bpl.s no_line_point_1
-
- cmp.w #0,d1
- bmi.s no_line_point_1
-
- cmp.w SS_Height+2(a0),d1
- bpl.s no_line_point_1
-
- move.l a0,a1
- bsr.s _Write_Pixel
- no_line_point_1
- PULLALL
-
- dbra d7,line_loop1
- rts
- HiSlope
- ; the line slope>1 so increment y and check for x
- ; d0=xs, d1=ys, d2=dx, d3=dy
-
- move.w d2,d5 dx into d5
- add.w d5,d5 error1
-
- move.w d5,d7 2*dx into d7
-
- move.w d3,d4 dy into d4
- add.w d4,d4 2*dy
-
- sub.w d4,d7 2*dx-2*dy
-
- move.w d7,d4 error2
-
- move.w d3,d7 dy as the counter
- subq.w #1,d7 dy-1
-
- add.w d2,d2 2*dx
- sub.w d3,d2 (2*dx)-dy:-initial value of D
-
- move.b (sp)+,d3
-
- line_loop2
- tst.w d2 test error
- bpl.s inc_y
- addq.w #1,d1 add ic onto xs
- add.w d5,d2 increment error
- bra.s point_2
- inc_y
- add.w d6,d0 add ic onto xs
- addq.w #1,d1 increment ys
- add.w d4,d2 increment error
- point_2
-
- PUSHALL
- cmp.w #0,d0 check x minimum
- bmi.s no_line_point_2
-
- cmp.w SS_Width+2(a0),d0
- bpl.s no_line_point_2
-
- cmp.w #0,d1
- bmi.s no_line_point_2
-
- cmp.w SS_Height+2(a0),d1
- bpl.s no_line_point_2
-
- move.b d3,d2
- move.l a0,a1
- bsr.s _Write_Pixel
- no_line_point_2
- PULLALL
-
- dbra d7,line_loop2
-
- PULL d2-d7/a2-a6
-
- rts
-
-
- _Write_Pixel:
- ; Duuuuuuuhhhhhhhhhhn
- ;
- ; input:- d0=x,d1=y
- ; d2=colour
- ; a0=destination screen struct
-
- ; probably not as tidy as other write pixels but it has
- ; to be like this for clipping
-
- PUSHALL
-
- move.l a0,a5
-
- move.l SS_Screen(a5),a0
-
- move.l SS_Width(a5),d3
- lsr.l #3,d3 byte width of a screen
-
- muls.l d3,d1
-
- move.w d0,d3
- lsr.w #3,d0 byte offset into the bitplane
- add.w d1,d0
-
- andi.w #%0000000000000111,d3
- subq.w #7,d3
- neg.w d3 bit offset of pixel
-
- move.l SS_Planes(a5),d6
- subq.l #1,d6
- add.w d0,a0 the destination byte in the bitmap
- pcol
- lsr.w d2 rotate the colour right
- bcc.s clrpoint carry clear = clear point
-
- bset d3,(a0)
- bra.s ploop
- clrpoint
- bclr d3,(a0)
- ploop
- move.l SS_Width(a5),d0
- lsr.l #3,d0
- muls.l SS_Height(a5),d0
- add.l d0,a0 increment onto next plane
-
- dbra d6,pcol loop back
-
- PULLALL
-
- rts
-
- _Screen_Clear
- ; clears a screen using the Blit Clear routine
- ; Should be self explanatory
-
- ; a0=screen structure
-
- PUSH d2-d7/a2-a6
-
- move.l a0,a5
- move.l SS_Screen(a5),a1
- move.l SS_Width(a5),d0
- lsr.l #3,d0
- muls.l SS_Height(a5),d0
- muls.l SS_Planes(a5),d0
- move.l #1,d1
- CALLGRAF BltClear
-
- PULL d2-d7/a2-a6
-
- rts
-
- _Show
- ; Performs the same job as the show macro in asm
- ; that is it shows the supplied screen
-
- PUSH d2-d7/a2-a6
-
- move.l View(a0),a1
- CALLGRAF LoadView
-
- PULL d2-d7/a2-a6
-
- rts
-
-
- ;---------------------------------------------------------------------
-
-
- ;-------- Fade Routines------------------------------------------------
- ; Fade_To_White(a0,a1) source screen,source colourmap
- ; Fade_To_Black(a0,a1) source screen,source colourmap
- ; Fade(a0,a1,a2) screen,source,destination
-
- _Fade_To_White
- ; Fades the screen to White and sets the colormap
- ; a0=screen
- ; a1=colortable
-
- PUSH d2-d7/a2-a6
-
- move.l a0,a5 store the screen
- move.l a1,a2 store the colortable
- White_Main_Loop
- move.l a2,a0 get the colortable
- sf fade_flag set the fade flag to false
- move.w (a0),d7 get the number of colurs
- ext.l d7 extend to longword
- subq.l #1,d7 -1 for dbra
- addq.l #4,a0 point to first colour value
- White_Fader_Loop
- move.l (a0),d0 colour red component
- cmp.l #$ffffffff,d0 full on ?
- beq.s White_red_done yes, so don't increment value
- add.l #$01010101,d0 else increment red component
- move.l d0,(a0) store the new value
- st fade_flag signal that we have made changes
- White_red_done
- addq.l #4,a0 offset to blue value
- move.l (a0),d0 get the blue component
- cmp.l #$ffffffff,d0 full on ?
- beq.s White_blue_done yes so don't change
- add.l #$01010101,d0 else increment value
- move.l d0,(a0) store the new value
- st fade_flag signal change
- White_blue_done
- addq.l #4,a0 same here as above but for green
- move.l (a0),d0 components
- cmp.l #$ffffffff,d0
- beq.s White_green_done
- add.l #$01010101,d0
- move.l d0,(a0)
- st fade_flag
- White_green_done
- addq.l #4,a0 point to next full colour
-
- ; loop for all colours
-
- dbra d7,White_Fader_Loop
-
- ; If this flag isn't set we are all done so exit out
-
- tst.b fade_flag
- beq.s White_fade_done
-
- ; else load the new values into the viewport
-
- move.l SS_ViewPort(a5),a0
- move.l a2,a1
- CALLGRAF LoadRGB32
-
- CALLGRAF WaitTOF
-
- bra White_Main_Loop
-
- White_fade_done
- PULL d2-d7/a2-a6
- rts
-
-
- _Fade_To_Black
- ; Fades the screen to black and clears the colormap
- ; operates in a similar way to the above procedure
- ; but instead of incrementing the colour values we decrement them.
-
- ; a0=screen
- ; a1=source colourmap
-
- PUSH d2-d7/a2-a6
-
- move.l a1,a2
- move.l a0,a5
-
- Black_Main_Loop
- move.l a2,a0
- sf fade_flag
- move.w (a0),d7
- ext.l d7
- subq.l #1,d7
- addq.l #4,a0
- Black_Fader_Loop
- move.l (a0),d0
- beq.s black_red_done
- sub.l #$01010101,d0
- move.l d0,(a0)
- st fade_flag
- black_red_done
- addq.l #4,a0
- move.l (a0),d0
- beq.s black_blue_done
- sub.l #$01010101,d0
- move.l d0,(a0)
- st fade_flag
- black_blue_done
- addq.l #4,a0
- move.l (a0),d0
- beq.s black_green_done
- sub.l #$01010101,d0
- move.l d0,(a0)
- st fade_flag
- black_green_done
- addq.l #4,a0
- dbra d7,Black_Fader_Loop
-
- tst.b fade_flag
- beq.s black_fade_done
-
- move.l SS_ViewPort(a5),a0
- move.l a2,a1
- CALLGRAF LoadRGB32
-
- CALLGRAF WaitTOF
-
- bra Black_Main_Loop
-
- black_fade_done
-
- PULL d2-d7/a2-a6
-
- rts
-
- _Fade
- ; fades between 2 colourmaps
- ; a0=screen
- ; a1=source cmap
- ; a2=destination cmap
-
- PUSH d2-d7/a2-a6
-
- move.l a0,a5
-
- move.l a2,a3
- move.l a1,a2
-
- move.l SS_Planes(a5),d1 allocate a temporary colourmap
- move.l #0,d0 for the fading
- bset d1,d0
- muls #12,d0
- add.l #8,d0
- move.l d0,d3
- move.l #MEMF_ANY,d1
- CALLEXEC AllocMem
- move.l d0,a4 storage for temporary cmap
-
- move.l a2,a0 copy the initial colourmap to the
- move.l a4,a1 temporary one
- move.l d3,d0
- CALLEXEC CopyMem
-
-
- Fader_Main_Loop
-
- move.l a5,-(sp) store the screen structure
-
- move.l a4,a5 temporary cmap into a5
-
- move.l a2,a0 both cmaps to temporary areas
- move.l a3,a1
-
- sf fade_flag clear the fade flag
-
- move.w (a0),d7 number of colours
- ext.l d7 extend to longword
- subq.l #1,d7
- addq.l #4,a5 update the cmaps to first colour
- addq.l #4,a1
- Fader_Loop
- move.l (a5),d0 source colour
- move.l (a1),d1 destination colour
- cmp.l d0,d1 compare the 2
- beq.s red_done if they are equal we are done
- bcs.s decrement_red less so decrement the value
- increment_red
- ; if we get to here we want to increment the value
- add.l #$01010101,d0
- bra.s put_red
- decrement_red
- sub.l #$01010101,d0 decrement the value
- put_red
- move.l d0,(a5) store the flag
- st fade_flag set the status flag
- red_done
- addq.l #4,a5 next component
- addq.l #4,a1
-
- move.l (a5),d0 does the same as above but for the
- move.l (a1),d1 blue components
- cmp.l d0,d1
- beq.s blue_done
- bcs.s decrement_blue
- increment_blue
- add.l #$01010101,d0
- bra.s put_blue
- decrement_blue
- sub.l #$01010101,d0
- put_blue
- move.l d0,(a5)
- st fade_flag
- blue_done
- addq.l #4,a5
- addq.l #4,a1
-
- move.l (a5),d0 does the same but for green components
- move.l (a1),d1
- cmp.l d0,d1
- beq.s green_done
- bcs.s decrement_green
- increment_green
- add.l #$01010101,d0
- bra.s put_green
- decrement_green
- sub.l #$01010101,d0
- put_green
- move.l d0,(a5)
- st fade_flag
- green_done
- addq.l #4,a5
- addq.l #4,a1
- dbra d7,Fader_Loop
-
- move.l (sp)+,a5
-
- tst.b fade_flag
- beq.s fade_done
-
- move.l SS_ViewPort(a5),a0
- move.l a4,a1
- CALLGRAF LoadRGB32
-
- CALLGRAF WaitTOF
- bra Fader_Main_Loop
-
- fade_done
-
- move.l SS_Planes(a5),d1
- move.l #0,d0
- bset d1,d0
- muls #12,d0
- add.l #8,d0
- move.l d0,d3
- move.l a4,a1
- CALLEXEC FreeMem free the temporary map
-
- PULL d2-d7/a2-a6
-
- rts
-
- ;---------------------------------------------------------------------
-
- ;-------- IFF Handling routines reading and writing of bitmaps ---------
- ; Save_IFF(a0,a1)=filename APTR, screen ADDR
- ; Load_IFF(a0,a1)=filename APTR, screen ADDR
-
- ; These procedures use the IFF_Library v23.2 by CHRISTIAN A. WEBE
- ; For more information please see the distribution along
- ; with this file
-
- _Load_IFF
- ; loads an iff into one a screen
- ; a0=filename
- ; a1=destination screen structure
- ;
-
- PUSH d2-d7/a2-a6
-
- movem.l a0-a1,-(sp)
-
- OPENLIB _IFFLib,0,_IFFBase open the library
-
- movem.l (sp)+,a0-a1
-
- move.l a1,-(sp) store the screen structure
-
- moveq.l #IFFL_MODE_READ,d0
- CALLIFF IFFL_OpenIFF open the IFF file
-
- move.l d0,a4 iff_handle
-
- move.l (sp)+,a5 screen structure into a5
-
- move.l SS_BitMap(a5),a0 destination bitmap into a0
-
- move.l a4,a1
- CALLIFF IFFL_DecodePic decode the iff picture data
-
- move.l a4,a0
- move.l SS_ColorTable(a5),a1
- bsr Full_Palette get the full 24 bit palette data
-
- move.l SS_ViewPort(a5),a0
- move.l SS_ColorTable(a5),a1
- CALLGRAF LoadRGB32 load the colour data
-
- move.l a4,a1
- CALLIFF IFFL_CloseIFF close the file
-
- CLOSELIB _IFFBase close the library
-
- PULL d2-d7/a2-a6
-
- rts
-
-
- _Save_IFF:
- ; save a screen as an iff
- ; a0=filename
- ; a1=screen to save
-
- PUSH d2-d7/a2-a6
-
- movem.l a0-a1,-(sp)
-
- OPENLIB _IFFLib,0,_IFFBase open the library
-
- movem.l (sp)+,a0-a1
-
- move.l a1,a5
-
- move.l #IFFL_MODE_WRITE,d0
- CALLIFF IFFL_OpenIFF open a new iff file
- move.l d0,a4
-
- ;------- Write the BMHD chunk to the IFF file
-
- move.l a4,a0
- move.l #ID_ILBM,d0
- move.l #ID_BMHD,d1
- CALLIFF IFFL_PushChunk make a new chunk
-
- move.l #20,d0
- move.l #MEMF_ANY,d1
- CALLEXEC AllocMem allocate temporary memory
-
- move.l d0,a3
-
- move.l a3,a0
- move.w SS_Width+2(a5),(a0)+ width in pixels
- move.w SS_Height+2(a5),(a0)+ height in pixels
- move.w #0,(a0)+ x offset
- move.w #0,(a0)+ y offset
- move.b SS_Planes+3(a5),(a0)+ number of bitplanes
- move.b #0,(a0)+ masking bit
- move.b #1,(a0)+ compression y/n
- move.b #0,(a0)+ pad bit
- move.w #0,(a0)+ transparent
- move.b #$2c,(a0)+ x aspect assume lowres
- move.b #$2c,(a0)+ y aspect assume lowres
- move.w SS_Width+2(a5),(a0)+ page width
- move.w SS_Height+2(a5),(a0)+ page height
-
- move.l a4,a0
- move.l a3,a1
- move.l #20,d0
- CALLIFF IFFL_WriteChunkBytes write the chunk to the file
-
- move.l a3,a1
- move.l #20,d0
- CALLEXEC FreeMem free the temp memory
-
- move.l a4,a0
- CALLIFF IFFL_PopChunk finished with this chunk
-
- ;-------- Done writing the BMHD chunk
-
- ;-------- Write the CMAP chunk
-
- move.l a4,a0
- move.l #ID_ILBM,d0
- move.l #ID_CMAP,d1
- CALLIFF IFFL_PushChunk set up a new chunk
-
- move.l #0,d0 clear d0
- move.l SS_Planes(a5),d1 nplanes into d1
- bset d1,d0 ncol
- muls #3,d0 *3
- move.l d0,d3
- move.l #MEMF_ANY,d1
- CALLEXEC AllocMem allocate some temp memory
-
- move.l d0,a3
-
- ; Here we want to copy the colourtable data into our temporary
- ; storage and pop it out onto our IFF file
-
- move.l a3,a0
- move.l SS_ColorTable(a5),a1
- move.l d3,d7
- subq.l #1,d7
- add.l #4,a1
- CMAP_loop
- move.l (a1)+,d0
- move.b d0,(a0)+
- dbra d7,CMAP_loop
-
- move.l a4,a0
- move.l a3,a1
- move.l d3,d0
- CALLIFF IFFL_WriteChunkBytes write the new chunk data
-
- move.l a3,a1
- move.l d3,d0
- CALLEXEC FreeMem free the temporary memory
-
- move.l a4,a0
- CALLIFF IFFL_PopChunk done with this chunk
-
- ;-------- Done writing the CMAP chunk to the file
-
- ;-------- Write the BODY data of the file
-
- move.l a4,a0
- move.l #ID_ILBM,d0
- move.l #ID_BODY,d1
- CALLIFF IFFL_PushChunk make a new chunk
-
- move.l SS_Width(a5),d0 WIDTH
- lsr.l #3,d0 /8
- muls.l SS_Height(a5),d0 *HEIGHT
- muls.l SS_Planes(a5),d0 *NPLANES
-
- move.l #MEMF_ANY,d1
- CALLEXEC AllocMem allocate some temp memory
-
- move.l d0,a3
-
- move.l #0,d5 compressed size
-
- move.l a3,a1 temporary memory
-
- move.l #0,d6 y counter
- Comp_Height_Loop
- move.l SS_Screen(a5),a0
- move.l d6,d0
- move.l SS_Width(a5),d1
- lsr.l #3,d1
- muls d1,d0
- add.l d0,a0
-
- ; set up for the compression loop
- ; compressed image data has to be interleaved
-
- move.l SS_Planes(a5),d7
- subq.l #1,d7
-
- Comp_Plane_Loop
- move.l a0,-(sp)
- move.l SS_Width(a5),d0
- lsr.l #3,d0
- move.l #IFFL_COMPR_BYTERUN1,d1 compress the current scan line
-
- CALLIFF IFFL_CompressBlock
-
- move.l (sp)+,a0
-
- add.l d0,d5
-
- move.l SS_Width(a5),d0
- lsr.l #3,d0
- muls.l SS_Height(a5),d0
-
- add.l d0,a0
- dbra d7,Comp_Plane_Loop onto the next plane
-
- move.l SS_Height(a5),d0
- subq.l #1,d0
- cmp.l d0,d6
- bge.s comp_done
- addq.l #1,d6
- bra.s Comp_Height_Loop onto the next scan line
- comp_done
- move.l a4,a0
- move.l a3,a1
- move.l d5,d0
- CALLIFF IFFL_WriteChunkBytes write the data
-
- move.l a3,a1
- move.l SS_Width(a5),d0 WIDTH
- lsr.l #3,d0 /8
- muls.l SS_Height(a5),d0 *HEIGHT
- muls.l SS_Planes(a5),d0 *NPLANES
-
- CALLEXEC FreeMem free our temporary memory
-
- move.l a4,a0
- CALLIFF IFFL_PopChunk pop this chunk off
-
- ;-------- Done writing the BODY data
-
- move.l a4,a1
- CALLIFF IFFL_CloseIFF finished with the file
-
- CLOSELIB _IFFBase close the library
-
- PULL d2-d7/a2-a6
-
- rts
-
- Full_Palette
- ; Gets the 24 bit colour information from an iff file
- ; needs IFF Library
- ; Internal IFF Routine used by load iff
-
- ; in:- a0=handle
- ; a1=destination colourmap
-
- PUSH a0-a1
-
- move.l a0,a1
- move.l #ID_CMAP,d0
- CALLIFF IFFL_FindChunk find the CMAP Chunk
-
- move.l d0,a2 store this memory
-
- PULL a0-a1
-
- addq.w #4,a2
-
- move.l (a2)+,d7 number of colours to
- move.l d7,d0 amount of data to strip out
- divs #3,d0
- move.w d0,(a1)+ number of colours into colormap
- addq.w #2,a1 onto first location
-
- subq.l #1,d7
- _col_loop
- moveq.l #0,d0
- move.b (a2),d0 first value
- lsl.l #8,d0 shift up
- move.b (a2),d0 get value again
- lsl.l #8,d0 shift up
- move.b (a2),d0 get value again
- lsl.l #8,d0 shift up
- move.b (a2)+,d0 get value again
-
- move.l d0,(a1)+ write colour data
- dbra d7,_col_loop
-
- rts
-
- ;-------- End of IFF Routines -----------------------------------------------
-
- ;-------- File handling Routines ----------------------------------------
- ; Load_Data(a0,d0,a1) filename, buffer length, destination
- ; Save_Data(a0,d0,d1) filename, buffer length, source
-
- _Load_Data
- ; Loads data from a file
-
- ; input a0=filename
- ; d0=byte size of data to read
- ; a1=destination buffer
-
- PUSH d2-d7/a2-a6
-
- move.l d0,-(sp)
-
- PUSHALL
-
- OPENLIB _DosLib,0,_DOSBase
-
- PULLALL
-
- move.l a0,d1 filename into d1
- move.l #MODE_OLDFILE,d2 type of file
- PUSH d0-d3/a0-a1 store registers
- CALLDOS Open open the file
- tst.l d0
- beq.s Open_Failed
- move.l d0,d5 store the filehandle
- PULL d0-d3/a0-a1 restore registers
-
- move.l d5,d1 filehandle into d1
- move.l a1,d2 desination for the data
- move.l (sp)+,d3 size of the data
-
- CALLDOS Read read the data
-
- move.l d5,d1 filehandle into d1
- CALLDOS Close close the file
-
- Open_Failed
-
- CLOSELIB _DOSBase
-
- PULL d2-d7/a2-a6
-
- rts
-
- _Save_Data
- ; saves data from a file
-
- ; input a0=filename
- ; d0=byte size of data to write
- ; a1=source buffer
-
- PUSH d2-d7/a2-a6
-
- move.l d0,-(sp)
-
- PUSHALL
-
- OPENLIB _DosLib,0,_DOSBase
-
- PULLALL
-
- move.l a0,d1 filename into d1
- move.l #MODE_NEWFILE,d2 type of file
- PUSH d0-d3/a0-a1 store registers
- CALLDOS Open open the file
- tst.l d0
- beq.s Save_Open_Failed
- move.l d0,d5 store the filehandle
- PULL d0-d3/a0-a1 restore registers
-
- move.l d5,d1 filehandle into d1
- move.l a1,d2 source for the data
- move.l (sp)+,d3 size of the data
-
- CALLDOS Write read the data
-
- move.l d5,d1 filehandle into d1
- CALLDOS Close close the file
-
- Save_Open_Failed
-
- CLOSELIB _DOSBase
-
- PULL d2-d7/a2-a6
-
- rts
- ;------------------------------------------------------------------------
-
-
- ;-------- Text handling routines -------------------------------------------
- ; Write_Text(a0,a1,d0,d1,d2,d3) screen, text, x, y, colour, length
- ; Num_To_String(d0) word
-
- _Write_Text
- ; writes the text to the screen using the current font
- ; a0=screen
- ; a1=text
- ; d0=x
- ; d1=y
- ; d2=colour
- ; d3=string length
-
- PUSH d2-d7/a2-a6
-
- exg.l a1,a0 get the screen and text into the right reg
-
- move.l SS_RastPort(a1),a1 rastport into a1
-
- movem.l a0-a1/d0-d3,-(sp)
- CALLGRAF Move move to the text position
- movem.l (sp)+,a0-a1/d0-d3
-
- movem.l a0-a1/d0-d3,-(sp)
- move.l d2,d0
- CALLGRAF SetAPen set the colour
- movem.l (sp)+,a0-a1/d0-d3
-
- move.l d3,d0 text length into d0
-
- CALLGRAF Text write the text
-
- PULL d2-d7/a2-a6
-
- rts
-
- _Num_To_String:
- ; converts a word value into a hex string
- ; string returned in a1
-
- ; d0=word
-
- PUSH d2-d7/a2-a6
-
- move.w d0,d1
- move.w d1,d2
- move.w d2,d3
-
- and.w #%0000000000001111,d0 get the lower byte value
- and.w #%0000000011110000,d1 get the successive bytes
- and.w #%0000111100000000,d2
- and.w #%1111000000000000,d3
-
- lsr.w #4,d1 get these values to the lowest
- lsr.w #8,d2 position by shifting
- lsr.w #6,d3
- lsr.w #6,d3
-
- cmp.b #9,d0 if we have a number
- bgt.s do_char_d0
- add.b #$30,d0 add the '0' onto it
- bra.s done_d0 all done
- do_char_d0
- sub.b #10,d0 else subtract 10
- add.b #$41,d0 add the 'A' onto it
- done_d0
- cmp.b #9,d1 do the same for the four other
- bgt.s do_char_d1 registers
- add.b #$30,d1
- bra.s done_d1
- do_char_d1
- sub.b #10,d1
- add.b #$41,d1
- done_d1
- cmp.b #9,d2
- bgt.s do_char_d2
- add.b #$30,d2
- bra.s done_d2
- do_char_d2
- sub.b #10,d2
- add.b #$41,d2
- done_d2
- cmp.b #9,d3
- bgt.s do_char_d3
- add.b #$30,d3
- bra.s done_d3
- do_char_d3
- sub.b #10,d3
- add.b #$41,d3
- done_d3
-
- lea num_string,a0
- move.b d3,(a0)+ write the data to the number string
- move.b d2,(a0)+
- move.b d1,(a0)+
- move.b d0,(a0)+
- move.b #0,(a0)+
-
- lea num_string,a1
-
- move.l a1,d0
-
- PULL d2-d7/a2-a6
-
- rts
-
-
- ;------------------------------------------------------------------------
-
- ;-------- Copper handling routines -------------------------------------
- ; Add_Copper(a0,a1) screen,copper list
-
- _Add_Copper
- ; Adds a copper list stream to the specified screen
- ; a0=screen
- ; a1=copper instructions
-
- PUSH d2-d7/a2-a6
-
- move.l a0,a5
- move.l a1,a2
-
- move.l #12,d0 enough space for a user copper struc
- move.l #MEMF_PUBLIC!MEMF_CLEAR,d1
- CALLEXEC AllocMem allocate memory for a user copper structure
-
- move.l d0,SS_UserCopperList(a5)
-
- move.l SS_UserCopperList(a5),a0
- move.l #5000,d0 allocate enough space for 5000 entries
- CALLGRAF UCopperListInit
-
- .Copper_Loop
- move.l (a2),d0
- cmp.l #$fffffffe,d0 check if we have a copper end instruction
- beq.s .Copper_Done
- move.w 2(a2),d0
- cmp.w #$fffe,d0 else check if it is a copper move
- bne.s .Copper_Move
- .Copper_Wait
- move.w (a2),d0 we want to feed a copper wait
- move.w #0,d1 into the copper stream
- move.b d0,d1 so decode and write it
- lsr.w #8,d0
- move.l SS_UserCopperList(a5),a1
- CALLGRAF CWait
- move.l SS_UserCopperList(a5),a1
- CALLGRAF CBump
- add.w #4,a2
- bra.s .Copper_Loop
- .Copper_Move
- move.w (a2)+,d0 decode the move instruction
- move.w (a2)+,d1 and feed it into the copper
- move.l SS_UserCopperList(a5),a1 stream
- CALLGRAF CMove
- move.l SS_UserCopperList(a5),a1
- CALLGRAF CBump
- bra.s .Copper_Loop
- .Copper_Done
-
- move.l SS_UserCopperList(a5),a1 all done so write the copper
- move.w #10000,d0 end instruction to the stream
- move.w #255,d1
- CALLGRAF CWait
- move.l SS_UserCopperList(a5),a1
- CALLGRAF CBump
-
- CALLEXEC Forbid latch the copper list onto
- move.l SS_ViewPort(a5),a0 the viewport
- move.l SS_UserCopperList(a5),vp_UCopIns(a0)
-
- move.l SS_View(a5),a0
- move.l SS_ViewPort(a5),a1
- CALLGRAF MakeVPort remake the viewport
-
- move.l SS_View(a5),a1
- CALLGRAF MrgCop merge the copperlist
-
- SHOW a5 show the screen
-
- CALLEXEC Permit
-
- PULL d2-d7/a2-a6
-
- rts
-
- ;------------------------------------------------------------------------
-
- ;-------- Input Handling Routines ---------------------------------------
- ; GetKey()
-
-
- _GetKey
-
- PUSH d2-d7/a2-a6
-
- moveq.l #0,d0 clear the register
- move.b $BFEC01,d0 get value from CIA chip
- not.b d0 manipulate it to form raw
- ror.b #1,d0 key code
-
- PULL d2-d7/a2-a6
-
- rts
-
- ;------------------------------------------------------------------------
-
-
- Section System_Data,DATA_F
- ; Data required by the above routines
-
- _DosLib
- DOSNAME
- even
- _graphics_lib
- GRAFNAME
- even
- _IFFLib
- IFFNAME
- even
-
- *TagItem structure
- vctags:
- dc.l VTAG_ATTACH_CM_SET,0
- dc.l VTAG_VIEWPORTEXTRA_SET,0
- dc.l VTAG_NORMAL_DISP_SET,0
- dc.l VTAG_END_CM,0
-
- Section System_BSS,BSS_F
- ; storage required by the above routines
- _IntuitionBase:
- ds.l 1
- _GfxBase
- ds.l 1
- _IFFBase
- ds.l 1
- _DOSBase
- ds.l 1
- _oldview
- ds.l 1
- clip_out
- ds.l 1
- line_flag
- ds.l 1
- fade_flag
- ds.l 1
- x_min
- ds.w 1
- x_max
- ds.w 1
- y_min
- ds.w 1
- y_max
- ds.w 1
- blitmod
- ds.w 1
- bltwidth
- ds.w 1
- blitsize
- ds.w 1
- bltstrt
- ds.w 1
- num_string
- ds.b 5
-
-